/*
 * array.hpp
 *
 *  Created on: Dec 16, 2011
 *      Author: ivanovak
 */

#ifndef ARRAY_HPP_
#define ARRAY_HPP_

#include "memory.h"
#include <algorithm>
#include <cstdlib>

template <typename T> class Array {
	static const int mult = 2;
	int arr_size;
	int capacity;
	T *a;
	void swap(Array& arr);

public:
    Array(size_t size);
    Array(const Array& arr);
    Array<T>& operator=(const Array& arr);
    const T& get(size_t index) const;
    void set(size_t index, T value);
    void push_back(T const& value);
    size_t size() const;
};

template <class T> void Array<T>::swap(Array& arr) {
	std::swap(arr_size, arr.arr_size);
	std::swap(capacity, arr.capacity);
	std::swap(a, arr.a);
}

template <class T> Array<T>::Array(size_t size): arr_size(0), capacity(size) {
	a = new T[size];
}

template <class T> Array<T>::Array(const Array& arr): arr_size(arr.size()), capacity(arr.size()) {
	arr_size = arr.size();
	a = new int[arr_size];

	for (int i = 0; i < arr_size; i++) {
		a[i] = arr.get(i);
	}
}

template <class T> Array<T>& Array<T>::operator=(const Array& arr) {
	if (this == &arr) {
		return *this;
	}

	Array tmp(arr);
	swap(tmp);
	return *this;
}

template <class T> size_t Array<T>::size() const {
	return arr_size;
}

template <class T> void Array<T>::push_back(T const& value)  {
	if (arr_size < capacity) {
			a[arr_size++] = value;
		} else {
			capacity *= 2;
			T *newA = new T[capacity];
			for (size_t i = 0; i < arr_size; i++) {
					newA[i] = a[i];
			}
			delete[] a;
			a = newA;
			push_back(value);
		}
}

template <class T> void Array<T>::set(size_t index, T value)  {
	a[index] = value;
}

template <class T> const T& Array<T>::get (size_t index) const {
	return a[index];
}

#endif /* ARRAY_HPP_ */
